/**
 * $Id: CMPP30MessageConvertorNew.java,v 1.3 2006/10/26 09:17:26 martin Exp $
 *
 * Copyright 2005 Skyinfo, Inc. All Rights Reserved.
 */
package com.haoxi.gateway.messageconvertor.impl;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.haoxi.gateway.cmppmsg.CMPP30DeliverMessage;
import com.haoxi.gateway.cmppmsg.CMPP30SubmitMessage;
import com.haoxi.gateway.cmppmsg.CMPP30SubmitRepMessage;
import com.haoxi.gateway.cmppmsg.CMPPCommon;
import com.haoxi.gateway.common.CommonMsgBean;
import com.haoxi.gateway.common.INFOConst;
import com.haoxi.gateway.common.Text;
import com.haoxi.gateway.messageconvertor.MessageConvertor;
import com.haoxi.gateway.runner.RunnerMgr;
import com.haoxi.gateway.runner.smscommand.BaseCommandObj;
import com.haoxi.gateway.runner.smscommand.SubmitCmd;
import com.haoxi.gateway.runner.smscommand.SubmitReportCmd;
import com.haoxi.gateway.runner.smscommand.SubmitStatusCmd;
import com.haoxi.gateway.runner.smscommand.UserMOCmd;

public class CMPP30MessageConvertorNew extends MessageConvertor {
    private static final Log log = LogFactory
            .getLog(CMPP30MessageConvertorNew.class);
    private String protcolVersion;
    private static final byte MSG_LEVEL = 3;
    private static final char[] SPECIAL_CHAR = { '\'' };

    /**
     * 构造函数
     */
    public CMPP30MessageConvertorNew(String gatewayCode) {
        super(gatewayCode);
        this.protcolVersion = INFOConst.CMPP30_VERSION;

    }

    /**
     * 根据BaseCommandObj构造网关需要的消息
     * 
     * @param BaseCommandObj obj
     * @return CommonMsgBean 见CommonMsgBean定义
     * @author martin
     */
    public CommonMsgBean convertCMDToCommonMsg(BaseCommandObj obj) {
        CommonMsgBean commonMsgBean = new CommonMsgBean();
        commonMsgBean.setGateWayCode(gatewayCode);
        String icpID = RunnerMgr.getInstance().getGatewayInfo().getIcp_id();

        try {
            if (obj instanceof SubmitCmd) {
                SubmitCmd subCmd = (SubmitCmd) obj;
                int pk_Total = 1;
                int pk_Number = 1;
                int registered_Delivery = subCmd.getReg_del();
                String service_Id = subCmd.getServiceId();
                int fee_UserType = subCmd.getFeeUserType();
                String fee_Terminal_Id = subCmd.getFeeMobile();
                int fee_Terminal_Type = subCmd.getFeeMobileType();
                int tp_Pid = subCmd.getTpPId();
                int tp_Udhi = subCmd.getTpUdhi();
                int msg_Fmt = subCmd.getMsgCoding();

                String fee_Type = subCmd.getFeeType();
                String fee_Code = String.valueOf(subCmd.getFeeCode());
                if (fee_Code.length() < 6) {
                    String tmp = "000000";
                    fee_Code = tmp.substring(0, 6 - fee_Code.length())
                            + fee_Code;
                }
                Date valid_Time = null;
                Date at_Time = null;
                String src_Terminal_Id = subCmd.getOrgMobile();
                String[] dest_Terminal_Id = subCmd.getDestMobile().split(",");
                int dest_Terminal_Type = subCmd.getDestMobileType();
                String content = subCmd.getMsgContent();
                byte[] msg_Content = null;
                int stype = subCmd.getStype();
                // PUSH转码
                if (stype == 200 || stype == 400) {
                    String strPos = "|~@$%^&~|";
                    String url = "";
                    String name = "";
                    int pos = content.indexOf(strPos);
                    url = content.substring(0, pos);
                    name = content.substring(pos + 9);
                    log.debug("push url:" + url);
                    log.debug("push name:" + name);
                    String pdu = getPushPdu(url, name);
                    msg_Content = convertStringToBytes(pdu);
                } else {
                    msg_Content = Text.textToByte(msg_Fmt, content);
                }
                String linkID = subCmd.getLinkID();
                subCmd.setMsgContent(convertSpecialChar(content));
                
                CMPP30SubmitMessage submitMsg = new CMPP30SubmitMessage(
                        pk_Total, pk_Number, registered_Delivery, MSG_LEVEL,
                        service_Id, fee_UserType, fee_Terminal_Id,
                        fee_Terminal_Type, tp_Pid, tp_Udhi, msg_Fmt, icpID,
                        fee_Type, fee_Code, valid_Time, at_Time,
                        src_Terminal_Id, dest_Terminal_Id, dest_Terminal_Type,
                        msg_Content, linkID);
                CMPPCommon.setMobileSequence(submitMsg);
                subCmd.setSequence(String.valueOf(submitMsg.getSequenceId()));
                // 打印原始消息
                log.debug(submitMsg);
                commonMsgBean.setBody(submitMsg.getBytes());
                commonMsgBean.setReserve(subCmd);
            }
        } catch (Exception ex) {
            if (null != obj) {
                log.error("baseObj : " + obj.toString());
            } else {
                log.error("baseObj is null !!!");
            }
            log
                    .error(
                            "Exception in CMPP30MessageConvertor.convertCMDToCommonMsg(): Exception",
                            ex);
            commonMsgBean = null;
        }
        return commonMsgBean;
    }

    /**
     * 转换从网关下发的消息,最终转换成BaseCommandObj
     * 
     * @param CommonMsgBean commonMsgBean 包含了网关下发的消息，网关编号
     * @BaseCommandObj 见BaseCommandObj定义
     * @author martin
     */
    public BaseCommandObj convertCommonMsgToCMD(CommonMsgBean commonMsgBean) {
        Object reserve = commonMsgBean.getReserve();
        int commid = commonMsgBean.getCommid();

        String connName = commonMsgBean.getConnName();
        byte[] body = commonMsgBean.getBody();
        byte[] msgidseq = new byte[12];
        int msgLength = body.length + 8;
        System.arraycopy(body, 0, msgidseq, 0, 12);
        if (CMPPCommon.CMPP_DELIVER == commid) {
            CMPP30DeliverMessage deliver = new CMPP30DeliverMessage(body);
            int deliverType = deliver.getRegisteredDeliver();
            // 普通MO消息
            if (0 == deliverType) {
                UserMOCmd mocmd = new UserMOCmd();
                mocmd.setCommandID(commid);
                mocmd.setCommandLength(msgLength);
                mocmd.setConnName(connName);
                mocmd.setDestMobile(deliver.getDestnationId());
                mocmd.setDestMobileType(0);
                mocmd.setGateWayCode(gatewayCode);
                mocmd.setLinkId(deliver.getLinkID());
                int msgFmt = deliver.getMsgFmt();
                mocmd.setMsgCoding(msgFmt);
                mocmd.setMsgContent(Text.getText(msgFmt, deliver
                        .getMsgContent()));
                mocmd.setMsgId(CMPPCommon.getMsgIdStr(deliver.getMsgId()));
                mocmd.setMsgId_bytes(deliver.getMsgId());
                mocmd.setOrgMobile(deliver.getSrcterminalId());
                mocmd.setOrgMobileType(0);
                mocmd.setReserved(reserve);
                mocmd.setSequence(String.valueOf(deliver.getSequenceId()));
                mocmd.setSpNumber(deliver.getDestnationId());
                mocmd.setServiceId(deliver.getServiceId());
                return mocmd;
            }
            // 状态报告
            else if (1 == deliverType) {
                SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
                SubmitReportCmd report = new SubmitReportCmd();
                report.setCommandID(commid);
                report.setCommandLength(msgLength);
                report.setConnName(connName);
                report.setDoneTime(format.format(deliver.getDoneTime()));
                report.setGatewayCode(gatewayCode);
                report.setMsgID(CMPPCommon
                        .getMsgIdStr(deliver.getStatusMsgId()));
                report.setReport(deliver.getStat());
                report.setMsgId_bytes(deliver.getStatusMsgId());
                report.setReserved(reserve);
                report.setSequence(String.valueOf(deliver.getSequenceId()));
                report.setUserNumber(deliver.getSrcterminalId());
                report.setUserNumberType(0);
                return report;
            } else {
                return null;
            }

        } else if (CMPPCommon.CMPP_SUBMIT_RESP == commid) {
            SubmitStatusCmd submitCmd = new SubmitStatusCmd();
            CMPP30SubmitRepMessage repmsg = new CMPP30SubmitRepMessage(body);
            submitCmd.setCommandID(commid);
            submitCmd.setCommandLength(msgLength);
            submitCmd.setMsgID(CMPPCommon.getMsgIdStr(repmsg.getMsgId()));
            submitCmd.setSequence(String.valueOf(repmsg.getSequenceId()));
            submitCmd.setStatus(String.valueOf(repmsg.getResult()));
            return submitCmd;
        }
        return null;
    }

    /**
     * @return Returns the protcolVersion.
     */
    public String getProtcolVersion() {
        return protcolVersion;
    }

    public String getPushPdu(String pushUrl, String pushName) {
        StringBuffer pdu = new StringBuffer();
        pdu.append("0605040B8423F0");
        pdu.append("DC0601AE02056A0045C60C03");
        // 将网址转换到UTF8进制
        pdu.append(stringToUTF8(handleUrl(pushUrl)));
        pdu.append("000103");
        // 将网址名字转换到utf8编码
        pdu.append(stringToUTF8(pushName));
        pdu.append("000101");
        return pdu.toString().toUpperCase();
    }

    public String handleUrl(String url) {
        String handleUrl = "";
        String head = "http://";
        try {
            if (url.indexOf(head) != -1) // 如果有http://头部，则除去头部
            {
                handleUrl = url.substring(head.length());
            } else // 返回原值
            {
                handleUrl = url;
            }

            return handleUrl;
        } catch (Exception ex) {

        }

        return handleUrl;
    }

    public String stringToUTF8(String s) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c >= 0 && c <= '\377') {
                String hex = Integer.toHexString(c).length() >= 2 ? Integer
                        .toHexString(c) : "0" + Integer.toHexString(c);
                sb.append(hex);
            } else {
                byte b[];
                try {
                    b = Character.toString(c).getBytes("UTF-8");
                } catch (Exception ex) {
                    log.error("", ex);
                    b = new byte[0];
                }
                for (int j = 0; j < b.length; j++) {
                    int k = b[j];

                    if (k < 0) {
                        k += 256;
                    }
                    sb.append(Integer.toHexString(k).toUpperCase());
                }

            }
        }

        return sb.toString().toUpperCase();
    }

    public byte[] convertStringToBytes(String srcBuff) {
        byte dest[] = (byte[]) null;
        try {
            dest = new byte[srcBuff.length() / 2];
            int j = 0;
            for (int i = 0; i < srcBuff.length();) {
                String subBuff = srcBuff.substring(i, i + 2);
                byte ab = (byte) Integer.parseInt(subBuff, 16);
                dest[j] = ab;
                i += 2;
                j++;
            }

            return dest;
        } catch (Exception exception) {
            return dest;
        }
    }

    public static String cut(String str, int bytesCount) {

        byte[] bytes = str.getBytes();
        char[] chars = new String(bytes, 0, bytesCount).toCharArray();
        char[] charsPlus = new String(bytes, 0, bytesCount + 1).toCharArray();

        if (chars.length == charsPlus.length) {
            return new String(bytes, 0, bytesCount - 1);
        }
        return new String(bytes, 0, bytesCount);

    }

    public String convertSpecialChar(String temp) {
        String result = "";
        if (SPECIAL_CHAR.length > 0) {
            for (int i = 0; i < SPECIAL_CHAR.length; i++) {
                int j = temp.indexOf(SPECIAL_CHAR[i]);
                while (-1 != j) {
                    result += temp.substring(0, j) + "/"
                            + Character.toString(SPECIAL_CHAR[i]);
                    temp = temp.substring(j + 1);
                    j = temp.indexOf(SPECIAL_CHAR[i]);
                }
                result += temp;
                temp = result;
            }
        }
        return result;
    }
}
